﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Resources;
using System.Globalization;

using TrainingCenterSystem;
using TrainingCenterSystem.VocabularyManagement;
using TrainingCenterSystem.VocabularyManagement.Exceptions;

namespace TrainingCenterWinClient.Forms
{
    public partial class TestSourceForm : Form
    {
        #region private members
        private CollectionHandler _collectionHandler;
        private TrainingCenter _trainingCenter;
        private ResourceManager _resMgr;
        private ArrayList _selectedSources;
        private string _allContexts;
        private string _errorCollectionExists;
        private string _errorOwningCollection;
        private string _errorContextExists;
        #endregion

        #region constructors
        public TestSourceForm(TrainingCenter trainingCenter, CollectionHandler collHandler, ArrayList selSources)
        {
            InitializeComponent();
            _collectionHandler = collHandler;
            _trainingCenter = trainingCenter;
            _selectedSources = selSources;
            this.initForm();
        }

        #endregion

        #region methods

        /// <summary>
        /// Initializes the form.
        /// </summary>
        private void initForm()
        {
            // init language
            this.UpdateLanguage(_trainingCenter.CurrentLanguageID);
            // init current collections
            this.initCurrentCollections();
            // init contexts
            this.initContexts();
            // init selectedSources

            // toggle the buttons
            this.toggleAddButton(false);
            this.toggleRemoveButton(false);            
        }

        /// <summary>
        /// Initializes the listbox for the currently open collections
        /// </summary>
        private void initCurrentCollections()
        {
            this.listCurrentCollections.Items.Clear();
            for (int i = 0; i < _collectionHandler.CurrentCollections.Count; i++)
            {
                this.listCurrentCollections.Items.Add(_collectionHandler.CurrentCollections[i].CollectionName);
            }
            if (this.listCurrentCollections.Items.Count>0)
                this.listCurrentCollections.SelectedIndex=0;
        }

        /// <summary>
        /// Initializes the listbox for the contexts
        /// </summary>
        private void initContexts()
        {
            this.listContexts.Items.Clear();
        }

        /// <summary>
        /// Updates the language of the form
        /// </summary>
        /// <param name="langID">the language-ID</param>
        private void UpdateLanguage(string langID)
        {
            try
            {
                // Set Language
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(langID);

                // Init ResourceManager
                _resMgr =
                    new ResourceManager("TrainingCenterWinClient.ReStrings",
                    typeof(TestSourceForm).Assembly);

                // assign localized strings to UI                
                this.Text = _resMgr.GetString("TestSourceForm_caption");
                this.lblCurrentCollections.Text = _resMgr.GetString("TestSourceForm_lblCurrentCollections");
                this.lblContexts.Text = _resMgr.GetString("TestSourceForm_lblContexts");
                this.lblSelectedCollections.Text = _resMgr.GetString("TestSourceForm_lblSelectedCollections");
                this.btnAddCollection.Text = _resMgr.GetString("TestSourceForm_btnAddCollection");
                this.btnOpenCollection.Text = _resMgr.GetString("TestSourceForm_btnOpenCollection");
                this.btnClose.Text = _resMgr.GetString("TestSourceForm_btnClose");
                this.btnRemoveCollection.Text = _resMgr.GetString("TestSourceForm_btnRemoveCollection");

                _allContexts = _resMgr.GetString("AllContexts");
                _errorCollectionExists = _resMgr.GetString("TestSourceForm_ErrorCollectionExists");
                _errorOwningCollection = _resMgr.GetString("TestSourceForm_ErrorOwningCollectionExists");
                _errorContextExists = _resMgr.GetString("TestSourceForm_ErrorContextExists");                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Handles the click-event on the Add-button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddCollection_Click(object sender, EventArgs e)
        {
            int contextIndex = -1;
            int collIndex = -1;
            // if '(all)' is selected
            if (this.listContexts.SelectedIndex == 0)
            {
                // take the selected collection and include all in the test            
                collIndex = this.listCurrentCollections.SelectedIndex;
                if (_selectedSources.Count==0)
                    _selectedSources.Add(_collectionHandler.CurrentCollections[collIndex]);                
                else
                    this.checkCollectionDuplicates(collIndex);

            }
            else if (this.listContexts.SelectedIndex>0)// otherwise, a specific context is selected
            {
                collIndex = this.listCurrentCollections.SelectedIndex;
                contextIndex = this.listContexts.SelectedIndex - 1;
                if (_selectedSources.Count==0)
                    _selectedSources.Add(_collectionHandler.CurrentCollections[collIndex].Contexts[contextIndex]);
                else
                    this.checkContextDuplicates(collIndex, contextIndex);
            }

            this.updateSelectedCollList();            
        }

        /// <summary>
        /// Checks if a collection is already selected
        /// </summary>
        /// <param name="collIndex">the collection index</param>
        private void checkCollectionDuplicates(int collIndex)
        { 
            string filename = _collectionHandler.CurrentCollections[collIndex].FileName;
            // check, if the complete collection is already added
            for (int i = 0; i < _selectedSources.Count; i++)
            {
                if (_selectedSources[i] is VocabularyCollection)
                {
                    // if collection is already added
                    if (((VocabularyCollection)_selectedSources[i]).FileName == filename)
                    {
                        // show message box
                        MessageBox.Show(_errorCollectionExists);
                        return;
                    }
                    else
                    {
                        // add the collection here
                        _selectedSources.Add(_collectionHandler.CurrentCollections[collIndex]);

                    }
                }
                else // if the source is a context
                {
                    // if it is a context that belongs to the collection
                    if (((VocabularyContext)_selectedSources[i]).CollectionID == filename)
                    {
                        // delete the context and add the collection
                        _selectedSources.RemoveAt(i);
                        _selectedSources.Add(_collectionHandler.CurrentCollections[collIndex]);
                    }
                }
            }            
        }

        /// <summary>
        /// Checks if a context is already selected
        /// </summary>
        /// <param name="collIndex">the collection index</param>
        /// <param name="contIndex">the context index</param>
        private void checkContextDuplicates(int collIndex, int contIndex)
        {
            string filename = ((VocabularyContext)_collectionHandler.CurrentCollections[collIndex].Contexts[contIndex]).CollectionID;
            string contID = ((VocabularyContext)_collectionHandler.CurrentCollections[collIndex].Contexts[contIndex]).ContextID;
            // check, if the complete collection is already added
            for (int i = 0; i < _selectedSources.Count; i++)
            {
                if (_selectedSources[i] is VocabularyCollection)
                {
                    // if the collection is already added
                    if (((VocabularyCollection)_selectedSources[i]).FileName == filename)
                    {
                        // show message box
                        MessageBox.Show(_errorOwningCollection);
                        return;
                    }
                }
                else // if it is a context
                {
                    // if the context is already added
                    if ((((VocabularyContext)_selectedSources[i]).ContextID == contID) &&
                        (((VocabularyContext)_selectedSources[i]).CollectionID == filename))
                    {
                        //show message box
                        MessageBox.Show(_errorContextExists);
                        return;
                    }
                    else
                    {
                        // add context
                        _selectedSources.Add(_collectionHandler.CurrentCollections[collIndex].Contexts[contIndex]);
                    }
                }
            }

        }

        /// <summary>
        /// Handles the SelectedIndexChanged-event on the listbox of current collections
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listCurrentCollections_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.listContexts.Items.Clear();
            int index=0;
            this.listContexts.Items.Add(_allContexts);
            if (this.listCurrentCollections.SelectedIndex >= 0)
            {
                index=this.listCurrentCollections.SelectedIndex;
                for (int i = 0; i < _collectionHandler.CurrentCollections[index].Contexts.Count; i++)
                    this.listContexts.Items.Add(((VocabularyContext)_collectionHandler.CurrentCollections[index].Contexts[i]).ContextName);
                this.listContexts.SelectedIndex = 0;
                this.toggleAddButton(true);
                return;
            }
            this.toggleAddButton(false);
        }

        /// <summary>
        /// Initializes the open-file-dialog
        /// </summary>
        /// <returns>true, if a file was selected</returns>
        private string openCollection()
        {
            string initialDir = "../testfiles";
            this.openCollectionFileDialog.DefaultExt = "xml";
            this.openCollectionFileDialog.Filter = "Xml File|*.xml";
            this.openCollectionFileDialog.InitialDirectory = initialDir;
            if (this.openCollectionFileDialog.ShowDialog() == DialogResult.OK)
                return this.openCollectionFileDialog.FileName;
            return null;
        }

        /// <summary>
        /// Handles the click event on the Open-button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpenCollection_Click(object sender, EventArgs e)
        {
            CollectionFileReader reader=null;
            string filename=null;
            filename = this.openCollection();
            if (filename!=null)
            {                
                try
                {
                    reader = new CollectionFileReader(_trainingCenter, _resMgr.GetString("ReadingError_Internal"), _resMgr.GetString("ReadingError_Access"));
                    reader.Read(filename);
                    _collectionHandler.AddCollection(reader.Collection);
                    this.addCurrentCollection();
                }
                catch (CollectionFileReadingException exc)
                {
                    MessageBox.Show(exc.Message);
                }
                finally
                {
                    reader.CloseReader();
                }              
            }
        }

        /// <summary>
        /// Adds a collection to the list if current collections
        /// </summary>
        private void addCurrentCollection()
        {
            this.listCurrentCollections.Items.Clear();
            for (int i = 0; i < _collectionHandler.CurrentCollections.Count; i++)
                this.listCurrentCollections.Items.Add(_collectionHandler.CurrentCollections[i].CollectionName);
            this.listCurrentCollections.SelectedIndex = 0;
        }

        
        /// <summary>
        /// Activates/deactivates the add-button
        /// </summary>
        /// <param name="active">Indicates if the button is active or not</param>
        private void toggleAddButton(bool active)
        {
            if (active)
                this.btnAddCollection.Enabled = true;
            else
                this.btnAddCollection.Enabled = false;
        }

        /// <summary>
        /// Activates/deactivates the Remove-button
        /// </summary>
        /// <param name="active">Indicates if the button is active or not</param>
        private void toggleRemoveButton(bool active)
        {
            if (active)
                this.btnRemoveCollection.Enabled = true;
            else
                this.btnRemoveCollection.Enabled = false;
        }

        /// <summary>
        /// Updates the list of selected sources
        /// </summary>
        private void updateSelectedCollList()
        {
            this.listSelectedCollections.Items.Clear();
            for (int i = 0; i < _selectedSources.Count; i++)
            {
                if (_selectedSources[i] is VocabularyCollection)
                    this.listSelectedCollections.Items.Add(((VocabularyCollection)_selectedSources[i]).CollectionName);
                else if (_selectedSources[i] is VocabularyContext)
                    this.listSelectedCollections.Items.Add(((VocabularyContext)_selectedSources[i]).ContextName);
            }
            if ((this.listSelectedCollections.Items.Count == 0)||(this.listSelectedCollections.SelectedIndex<0))
                this.toggleRemoveButton(false);
        }

        /// <summary>
        /// Handles the click event on the Remove-button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRemoveCollection_Click(object sender, EventArgs e)
        {
            int index = this.listSelectedCollections.SelectedIndex;
            _selectedSources.RemoveAt(index);
            this.updateSelectedCollList();
        }

        /// <summary>
        /// Handles the SelectedIndexChanged event on the listbox of selected sources
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listSelectedCollections_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.listSelectedCollections.SelectedIndex < 0)
                this.toggleRemoveButton(false);
            else
                this.toggleRemoveButton(true);
        }

        /// <summary>
        /// Handles the click event on the Close-button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion
    }
}
